﻿
namespace ZDS.Test

open System

open NUnit.Framework
open FsUnit

open ZDS
open TestUtility

[<TestFixture>]
type TestStaticLinkList() =

    [<Test>]
    member this.TestEmpty() =
        let x = new ZStaticLinkList<int>(1)
        x.Size |> should equal 0

        x |> should equal []

    [<Test>]
    member this.TestAppend() =
        let x = new ZStaticLinkList<int>(3)
        for index = 1 to x.Capacity do
            x.Append <| index*index

        x.Size |> should equal 3
        x |> should equal [1;4;9]

        (fun() -> x.Append 100)
        |> getErrorCode
        |> should equal ErrorCode.Full

    [<Test>]
    member this.TestGetSet() =
        let y = new ZStaticLinkList<int>(10)
        (fun() -> y.[0] |> ignore)
        |> getErrorCode
        |> should equal ErrorCode.OutofRange

        for index = 1 to 3 do
            y.Append index

        y.[1] |> should equal 2
        y.[2] <- 99
        y.[2] |> should equal 99

        y |> should equal [1;2;99]

        (fun() -> y.[3] <- 66)
        |> getErrorCode
        |> should equal ErrorCode.OutofRange

    [<Test>]
    member this.TestInsertHead() =
        let x = new ZStaticLinkList<int>(3)
        (fun() -> x.Insert 100 -1)
        |> getErrorCode
        |> should equal ErrorCode.OutofRange

        for index = 1 to 2 do
            x.Insert 0 (index*index)

        x.Append 99 // to verify the rear is correctly set
        x |> should equal [4;1;99]
        
        (fun() -> x.Insert 0 99)
        |> getErrorCode
        |> should equal ErrorCode.Full

    [<Test>]
    member this.TestInsertRear()=
        let x = new ZStaticLinkList<int>(5)

        for index = 1 to 3 do
            x.Insert x.Size (index*2)
        
        x.Append 8
        x.Append 9
        x |> should equal [2;4;6;8;9]

        x.[x.Size-1] <- 100
        x |> should equal [2;4;6;8;100]

        (fun() -> x.Insert 1 3)
        |> getErrorCode
        |> should equal ErrorCode.Full

    [<Test>]
    member this.TestInsertMiddle() =
        let x = new ZStaticLinkList<int>(8)

        for index = 1 to 3 do
            x.Append <| index*index

        x.Insert 1 88
        x.Insert 1 99
        x |> should equal [1;99;88;4;9]

        x.Insert 3 66
        x.Insert 5 100
        x |> should equal [1;99;88;66;4;100;9]

        x.Append 3
        x |> should equal [1;99;88;66;4;100;9;3]

        (fun() -> x.Append -1)
        |> getErrorCode
        |> should equal ErrorCode.Full

    [<Test>]
    member this.TestRemoveHead() =
        let x = new ZStaticLinkList<int>(5)
        (fun() -> x.Remove 0 |> ignore)
        |> getErrorCode
        |> should equal ErrorCode.Empty

        for index = 1 to x.Capacity do
            x.Append <| index * index

        seq {
            for index = 1 to 3 do
                yield (x.Remove 0)
        }
        |> should equal [1;4;9]
        x.Size |> should equal 2

        x.Append 100
        x |> should equal [16;25;100]

    [<Test>]
    member this.TestRemoveRear()=
        let x = new ZStaticLinkList<int>(5)

        for index = 1 to x.Capacity do
            x.Append <| index * index

        (fun() -> x.Remove 8 |> ignore)
        |> getErrorCode
        |> should equal ErrorCode.OutofRange

        seq {
            for index = 1 to 3 do
                yield (x.Remove (x.Size-1))
        }
        |> should equal [25;16;9]
        x.Size |> should equal 2

        x.Append 100
        x |> should equal [1;4;100]

        seq {
            for index = 1 to 3 do
                yield (x.Remove (x.Size-1))
        }
        |> should equal [100;4;1]
        x.Size |> should equal 0

    [<Test>]
    member this.TestRemoveMiddle()=
        let y = new ZStaticLinkList<int>(5)

        y.Append 6
        y.Append 9

        y.Remove 1 |> should equal 9

        y.Insert 0 8
        y.Append 10
        y.Append 44

        y.Remove 2 |> should equal 10
        y.Remove 0 |> should equal 8
        y |> should equal [6;44]

        y.Remove 1 |> should equal 44
        y.Remove 0 |> should equal 6

        (fun() -> y.Remove 0 |> ignore)
        |> getErrorCode
        |> should equal ErrorCode.Empty

        
        




